<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>编写简单的显示器</title>
</head>

<body>
    显示分辨率是**64X32**的像素，并且是**单色**的。某像素点为1则屏幕上显示相应像素点，为0则不显示。但某个像素点由有到无则进位标识被设置为1，可以用来进行冲撞检测。

    <div id="boxs" style="overflow: auto;width:320px;border: 1px solid #666;"></div>
    <script>
        (function () {
            function CPU() {/*...*/ };
            function Screen() {
                this.rows = 32;//32行
                this.columns = 64;//64列
                this.resolution = this.rows * this.columns;
                this.bitMap = new Array(this.resolution);//像素点阵
                this.clear = function () {
                    this.bitMap = new Array(this.resolution);
                }
                this.render = function () { };//显示渲染
                this.setPixel = function (x, y) {
                    // 显示溢出处理
                    if (x > this.columns - 1) while (x > this.columns - 1) x -= this.columns;
                    if (x < 0) while (x < 0) x += this.columns;

                    if (y > this.rows - 1) while (y > this.rows - 1) y -= this.rows;
                    if (y < 0) while (y < 0) y += this.rows;

                    //获取点阵索引
                    var location = x + (y * this.columns);
                    //反向显示,假设二值颜色黑白分别用1、0代表,那么值为1那么就将值设置成0,同理0的话变成1
                    this.bitMap[location] = this.bitMap[location] ^ 1;

                    return !this.bitMap[location];
                }
            };
            function Keyboard() {/*...*/ };
            function Speaker() {/*...*/ };
            window.CHIP8 = function () {
                var c8 = new CPU();
                c8.screen = new Screen();
                c8.speaker = new Speaker();
                c8.input = new Keyboard();
                return c8;
            };
        })();

var chip8 = CHIP8();
chip8.screen.render = function () {//自定义实现显示渲染
    var boxs = document.getElementById("boxs");
    boxs.innerHTML = "";
    for (var i of this.bitMap) {
        var d = document.createElement("span");
        d.style = "width: 5px;height: 5px;float: left;";
        d.style.backgroundColor = i ? "#000" : "#fff";
        boxs.appendChild(d);
    }
};
/** 测试 **/
chip8.screen.setPixel(2, 2);//设置x,y坐标像素
chip8.screen.render();
chip8.screen.setPixel(2, 2);//设置x,y坐标像素

        //随机数字测试
        function randomNum(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }
        var test = [[[1, 1], [2, 1], [3, 1], [1, 2], [3, 2], [1, 3], [3, 3], [1, 4], [3, 4], [1, 5], [2, 5], [3, 5]], [[6, 1], [6, 2], [6, 3], [6, 4], [6, 5]], [[10, 1], [11, 1], [12, 1], [10, 2], [12, 2], [10, 3], [12, 3], [10, 4], [12, 4], [10, 5], [11, 5], [12, 5]], [[14, 1], [15, 1], [16, 1], [16, 2], [14, 3], [15, 3], [16, 3], [16, 4], [14, 5], [15, 5], [16, 5]], [[19, 1], [20, 1], [21, 1], [19, 2], [21, 2], [19, 3], [21, 3], [19, 4], [21, 4], [19, 5], [20, 5], [21, 5]], [[23, 1], [24, 1], [25, 1], [23, 2], [23, 3], [24, 3], [25, 3], [25, 4], [23, 5], [24, 5], [25, 5]], [[28, 1], [29, 1], [30, 1], [28, 2], [30, 2], [28, 3], [30, 3], [28, 4], [30, 4], [28, 5], [29, 5], [30, 5]], [[32, 1], [33, 1], [34, 1], [34, 2], [34, 3], [34, 4], [34, 5]], [[37, 1], [38, 1], [39, 1], [37, 2], [39, 2], [37, 3], [39, 3], [37, 4], [39, 4], [37, 5], [38, 5], [39, 5]], [[41, 1], [42, 1], [43, 1], [41, 2], [43, 2], [41, 3], [42, 3], [43, 3], [43, 4], [41, 5], [42, 5], [43, 5]], [[47, 1], [47, 2], [47, 3], [47, 4], [47, 5]], [[51, 1], [51, 2], [51, 3], [51, 4], [51, 5]], [[56, 1], [56, 2], [56, 3], [56, 4], [56, 5]], [[59, 1], [60, 1], [61, 1], [61, 2], [59, 3], [60, 3], [61, 3], [61, 4], [59, 5], [60, 5], [61, 5]], [[2, 7], [2, 8], [2, 9], [2, 10], [2, 11]], [[5, 7], [6, 7], [7, 7], [5, 8], [5, 9], [6, 9], [7, 9], [7, 10], [5, 11], [6, 11], [7, 11]], [[11, 7], [11, 8], [11, 9], [11, 10], [11, 11]], [[14, 7], [15, 7], [16, 7], [16, 8], [16, 9], [16, 10], [16, 11]], [[20, 7], [20, 8], [20, 9], [20, 10], [20, 11]], [[23, 7], [24, 7], [25, 7], [23, 8], [25, 8], [23, 9], [24, 9], [25, 9], [25, 10], [23, 11], [24, 11], [25, 11]], [[28, 7], [29, 7], [30, 7], [30, 8], [28, 9], [29, 9], [30, 9], [28, 10], [28, 11], [29, 11], [30, 11]], [[33, 7], [33, 8], [33, 9], [33, 10], [33, 11]], [[37, 7], [38, 7], [39, 7], [39, 8], [37, 9], [38, 9], [39, 9], [37, 10], [37, 11], [38, 11], [39, 11]], [[41, 7], [42, 7], [43, 7], [43, 8], [41, 9], [42, 9], [43, 9], [43, 10], [41, 11], [42, 11], [43, 11]], [[46, 7], [47, 7], [48, 7], [48, 8], [46, 9], [47, 9], [48, 9], [46, 10], [46, 11], [47, 11], [48, 11]], [[50, 7], [51, 7], [52, 7], [50, 8], [50, 9], [51, 9], [52, 9], [52, 10], [50, 11], [51, 11], [52, 11]], [[55, 7], [56, 7], [57, 7], [57, 8], [55, 9], [56, 9], [57, 9], [55, 10], [55, 11], [56, 11], [57, 11]], [[59, 7], [60, 7], [61, 7], [61, 8], [61, 9], [61, 10], [61, 11]], [[1, 13], [2, 13], [3, 13], [3, 14], [1, 15], [2, 15], [3, 15], [1, 16], [1, 17], [2, 17], [3, 17]], [[5, 13], [6, 13], [7, 13], [5, 14], [7, 14], [5, 15], [6, 15], [7, 15], [7, 16], [5, 17], [6, 17], [7, 17]], [[10, 13], [11, 13], [12, 13], [12, 14], [10, 15], [11, 15], [12, 15], [12, 16], [10, 17], [11, 17], [12, 17]], [[15, 13], [15, 14], [15, 15], [15, 16], [15, 17]], [[19, 13], [20, 13], [21, 13], [21, 14], [19, 15], [20, 15], [21, 15], [21, 16], [19, 17], [20, 17], [21, 17]], [[23, 13], [24, 13], [25, 13], [25, 14], [23, 15], [24, 15], [25, 15], [25, 16], [23, 17], [24, 17], [25, 17]], [[28, 13], [29, 13], [30, 13], [30, 14], [28, 15], [29, 15], [30, 15], [30, 16], [28, 17], [29, 17], [30, 17]], [[32, 13], [33, 13], [34, 13], [32, 14], [32, 15], [33, 15], [34, 15], [34, 16], [32, 17], [33, 17], [34, 17]], [[37, 13], [38, 13], [39, 13], [39, 14], [37, 15], [38, 15], [39, 15], [39, 16], [37, 17], [38, 17], [39, 17]], [[41, 13], [42, 13], [43, 13], [43, 14], [43, 15], [43, 16], [43, 17]], [[46, 13], [47, 13], [48, 13], [48, 14], [46, 15], [47, 15], [48, 15], [48, 16], [46, 17], [47, 17], [48, 17]], [[50, 13], [51, 13], [52, 13], [50, 14], [52, 14], [50, 15], [51, 15], [52, 15], [52, 16], [50, 17], [51, 17], [52, 17]], [[55, 13], [57, 13], [55, 14], [57, 14], [55, 15], [56, 15], [57, 15], [57, 16], [57, 17]], [[60, 13], [60, 14], [60, 15], [60, 16], [60, 17]], [[1, 19], [3, 19], [1, 20], [3, 20], [1, 21], [2, 21], [3, 21], [3, 22], [3, 23]], [[5, 19], [6, 19], [7, 19], [7, 20], [5, 21], [6, 21], [7, 21], [7, 22], [5, 23], [6, 23], [7, 23]], [[10, 19], [12, 19], [10, 20], [12, 20], [10, 21], [11, 21], [12, 21], [12, 22], [12, 23]], [[14, 19], [15, 19], [16, 19], [14, 20], [14, 21], [15, 21], [16, 21], [16, 22], [14, 23], [15, 23], [16, 23]], [[19, 19], [21, 19], [19, 20], [21, 20], [19, 21], [20, 21], [21, 21], [21, 22], [21, 23]], [[23, 19], [24, 19], [25, 19], [25, 20], [25, 21], [25, 22], [25, 23]], [[28, 19], [30, 19], [28, 20], [30, 20], [28, 21], [29, 21], [30, 21], [30, 22], [30, 23]], [[32, 19], [33, 19], [34, 19], [32, 20], [34, 20], [32, 21], [33, 21], [34, 21], [34, 22], [32, 23], [33, 23], [34, 23]], [[37, 19], [38, 19], [39, 19], [37, 20], [37, 21], [38, 21], [39, 21], [39, 22], [37, 23], [38, 23], [39, 23]], [[42, 19], [42, 20], [42, 21], [42, 22], [42, 23]], [[46, 19], [47, 19], [48, 19], [46, 20], [46, 21], [47, 21], [48, 21], [48, 22], [46, 23], [47, 23], [48, 23]], [[50, 19], [51, 19], [52, 19], [52, 20], [50, 21], [51, 21], [52, 21], [52, 22], [50, 23], [51, 23], [52, 23]], [[55, 19], [56, 19], [57, 19], [55, 20], [55, 21], [56, 21], [57, 21], [57, 22], [55, 23], [56, 23], [57, 23]], [[59, 19], [60, 19], [61, 19], [59, 20], [59, 21], [60, 21], [61, 21], [61, 22], [59, 23], [60, 23], [61, 23]], [[1, 25], [2, 25], [3, 25], [1, 26], [1, 27], [2, 27], [3, 27], [3, 28], [1, 29], [2, 29], [3, 29]], [[5, 25], [6, 25], [7, 25], [7, 26], [7, 27], [7, 28], [7, 29]], [[10, 25], [11, 25], [12, 25], [10, 26], [10, 27], [11, 27], [12, 27], [12, 28], [10, 29], [11, 29], [12, 29]], [[14, 25], [15, 25], [16, 25], [14, 26], [16, 26], [14, 27], [15, 27], [16, 27], [16, 28], [14, 29], [15, 29], [16, 29]], [[19, 25], [20, 25], [21, 25], [19, 26], [19, 27], [20, 27], [21, 27], [19, 28], [21, 28], [19, 29], [20, 29], [21, 29]], [[24, 25], [24, 26], [24, 27], [24, 28], [24, 29]]];
        setInterval(() => {
            var i = test[randomNum(0, test.length)];
            for (var j of i) {
                chip8.screen.setPixel(j[0], j[1]);
            }
            chip8.screen.render();
        }, 1000 / 60); 
    </script>
</body>

</html>